//
//  VisitorPattern.swift
//  AQDeal
//
//  Created by zhangjikuan on 2020/4/1.
//  Copyright © 2020 hsgd. All rights reserved.
//

/// 六大基本设计原则
/// Six Basic Principles
/// 1. Single-Responsesibility Principle
/// 2. Open-Closed Principle
/// 3. Demeter Principle  Least Knowledge Principle
/// 4. Liskov Substitution Principle LSP
/// 5. Dependency Dependency inversion principle
///
/// 23 kinds Design patterns

/// 1.Creation

/// 2.Structural Pattern

/// 3.Behavioral Pattern


import Foundation




/// 抽象被访问元素 Abstract visited element
class VisitElement: NSObject {
    func accept(vistor:Visitor) {
    }
}
/// 抽象访问者 Abstract vistor
class Visitor: NSObject {
    func vistA(element: VisitElement) {
    }
    func visitB(element: VisitElement) {
    }
}
/// 具体访问者 constract visitor A
class VisitorA: Visitor {
    override func vistA(element: VisitElement) {
        NSLog("No1 visit1 %@", element)
    }
    override func visitB(element: VisitElement) {
        NSLog("No1 visit2 %@", element)
    }
}
/// 具体访问者B Constract Visitor B
class VisitorB: Visitor {
    override func vistA(element: VisitElement) {
        NSLog("No2 visit1 %@", element)
    }
    override func visitB(element: VisitElement) {
        NSLog("No2 visit2 %@", element)
    }
}

/// 具体访问元素A
class VisitElementA: VisitElement {
    override func accept(vistor: Visitor) {
        vistor.vistA(element: self)
    }
}

/// 具体访问元素B
class VisitElementB: VisitElement {
    override func accept(vistor: Visitor) {
        vistor.visitB(element: self)
    }
}

class Client: NSObject {
    func begin() {
        let visit1 = VisitorA()
        let visit2 = VisitorB()
        let element1 = VisitElementA()
        let element2 = VisitElementA()
        let element3 = VisitElementA()
        let element4 = VisitElementB()
        let element5 = VisitElementB()
        let element6 = VisitElementB()
        let array = [element1,element2,element3,element4,element5,element6]
        for element in array {
            let number = arc4random()
            if number%2 == 0 {
                element.accept(vistor: visit1)
            } else {
                element.accept(vistor: visit2)
            }
        }
    }
}
